9.6 Lambda Expressions

A lambda expression is an anonymous function definition to which a function parameter with the same signature can be bound.

To create a lambda expression, the lambda symbol is used in place of a function name. That is, f(x, y)→x^y as an anonymous definition is written λ(x,y)→x^y. The display form of a lambda expression simply omits the function name: λ(x, y)→x^y. An alternate syntax for single-parameter lambda expressions omits the parameter parenthesis. That is, λ(x)→x^2 can be entered as λx→x^2.

Lambda expressions must be typed; this example elaborates a set: λʂ(x)→{log(2, x), x^2} but note the non-real function-type, normally indicated by a bold-face non-serif function name, is missing in the displayed form along with the function name. Inspection of the text-output area reveals the typed form: λʂx→{log(2,x),x^2}.

Like any other expression, a standalone lambda expression can be evaluated by providing arguments. It is not usually useful, but (λx→x^2)(3) – which is automatically generated from (x^2)(3) and displays the same as (f(x)→x^2)(3) – can be evaluated. But as mentioned above, a lambda expression can be passed, unevaluated, as a parameter to a function. In the latter's elaboration, the function parameter can be evaluated or passed on, unevaluated.

To see this in action, consider the definition c(d(x), x)→d(x) and the evaluation of c(λ(x)→x^2, 3). During activation, formal parameter d(x) is bound to the lambda expression and formal parameter x is bound to 3. In the elaboration of c, d(x) is evaluated as x^2. Contrast this with the definitions a(x)→b(x) and b(w)→w^2 along with the evaluation of a(b(3)). Here, a is passed the real result of b(3), as evaluated by the non-local b(w).

Three questions arise: how does a function expression in an elaboration know to be bound directly or via a function parameter? what determines whether a function will be passed or evaluated? and how can a function already defined be passed as a parameter.

The answer to the first question is a matter of scope and the observation that the scope of an elaboration is nested within the scope of the function's parameters and that within the workspace. Thus, a function expression will be bound to a function parameter, or to a function in the workspace, or binding will fail. If bound to a function parameter, the call chain will ultimately end in a lambda expression.

The second question is answered by noticing whether a lambda expression is used. The two expressions e(b(x)) (in which b is invoked) and e(λ(x)→b(x)), (in which b is passed as a parameter) have a different appearance.

To answer the third question, consider the serial tuple

(h(m(x), x)→m(x), g(n(x), x)→h(λ(x)→n(x), x), f(x)→x^2, g(λ(x)→f(x), 2)).

 


Working from right to left, f(x) is passed as a lambda expression to function g, which passes it in turn to function h using another lambda expression.

9.6.1 Quadrature, revisited

Using quadrature, the definite integral of a function is computed numerically. The implementation in §9.3.5 binds the quadrature algorithm to a non-local function. The function-parameter version of this is realized as

q(f(x), l, u, w)→l+w÷2≥u?0:w⋅f(l+w÷2)+q(λ(x)→f(x), l+w, u, w).

 


Now q can be evaluated using q(λ(x)→x^2, 0, 1, 0.1).